#include "String.h"
#include<string.h>
#include<stdexcept>
   
String::String(){
	this->elemento= new char[1];
        this->elemento[0]= '\0';
        this->largo = 0;
    };
		
    String::String(char* c){
        int largo= strlen(c);
        this->largo = largo;
        this->elemento = new char[largo + 1];
        strcpy(this->elemento ,c);

    };

    String::String(const String &s){
        //
        int largo= strlen(s.elemento);
        this->largo = s.largo;
        this->elemento= new char[largo + 1];
        strcpy(this->elemento, s.elemento);

    };

    char* String::getElemento()const{
            return this->elemento;
    };

     int String::getLargo()const{
        return this->largo;
    }

    void String::setLargo(int l){
       this->largo= l;
     }


    String& String::operator=(const String &a){
        delete[] this->elemento;
       int largo= strlen(a.elemento);
        this->largo= largo;
        this->elemento= new char[largo + 1];
        strcpy(this->elemento,a.elemento);
        return *this;
    };

    String& String::operator=(char* c){
        delete[] this->elemento;
       int largo= strlen(c);
       this->largo= largo;
        this->elemento= new char[largo + 1];
        strcpy(this->elemento,c);
        return *this;
    };

     void String::setElemento(char* c){
        delete[] this->elemento;
        int l = 0;
        while(c[l] != '\0'){
            l++;
        }
        this->largo = l;
        this->elemento= new char[largo + 1];
        for(int i=0; i<l; i++){
            elemento[i]=c[i];
        }
        elemento[l]='\0';


    };
    String String::operator+(char* c){
        int largoE= strlen(this->elemento);
        int largo = strlen(c);
        this->largo= largo;
        String aux= String();
        aux.elemento= new char[largoE + largo +1];
        aux.largo= largoE + largo;
        strcpy(aux.elemento, this->elemento);
        strcat(aux.elemento, c);
        return aux;
    };

    String String::operator+(const String& s){
        int largoE= strlen(this->elemento);
        int largo = strlen(s.elemento);
        String aux = String();
        aux.elemento= new char[largoE + largo +1];
        aux.largo= largoE + largo;
        strcpy(aux.elemento, this->elemento);
        strcat(aux.elemento, s.elemento);
        return aux;
    };

    bool String::operator==(const String &s){
        return(strcmp(this->elemento, s.elemento)== 0);
    };

    bool String::operator==(char* c){
        return(strcmp(this->elemento, c)== 0);
    };

    bool String::operator<(const String& s){
        return(strcmp(this->elemento, s.elemento)< 0);
    };

    bool String::operator<(char* c){
        return(strcmp(this->elemento, c)< 0);
    };

    bool String::operator>(const String &s){
        return(strcmp(this->elemento, s.elemento)> 0);
    };


    bool String::operator>(char* c){
        return(strcmp(this->elemento, c)> 0);
    };

    char String::operator[](int n){
        if((n>=0) && n< (this->largo))
            return this->elemento[n];
        else
            throw out_of_range("Indice fuera de rango\n");
    };

    int String::lenght(){
        return this->largo;
    };

    String String::substring(int i, int j){
        if((i<j)&& ((i>=0) && i< (this->largo))&& ((j>=0) && j< (this->largo))){
            char* c = new char[(j - i) +2];
        int h =0;
        for(int k=i; k<= j; k++){
            c[h]= this->elemento[k];
            h++;
        }
        c[j-i+1] = '\0';
        String aux;
        aux = String(c);
        return aux;
        }else{
            throw out_of_range("Indices fuera de rango\n");
        }
        };

    String::~String(){
        delete []this->elemento;
    }

    ostream & operator<<(ostream& o, const String &s){
        o << s.getElemento();
        return o;
    };

  istream& operator >> (istream &i, String &s){
    char* aux = new char[256];
    i >> aux;
    i.ignore();
    s.setElemento(aux);
    return i;
}
